package demo.retry;


import lombok.Data;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author : GuoFei
 * @date : 2018/12/14 15:36
 */
public class RetryUtil {

    public static List<RetryManage> reTryList = new ArrayList<>();

    static ScheduledExecutorService timer = null;

    public static void addRetry(RetryObj retryObj,int times,int period){
        reTryList.add(new RetryManage(times, period, retryObj));

        if (timer == null) {
            timer = Executors.newScheduledThreadPool(1);
        }
        timer.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Iterator<RetryManage> listIt = reTryList.iterator();
                RetryManage retryManage;
                while (listIt.hasNext()) {
                    retryManage = listIt.next();
                    if (retryManage.run()) {
                        listIt.remove();
                    }
                }
            }
        }, 0L, 1L, TimeUnit.SECONDS);
        if (reTryList.size() == 0) {
            timer.shutdown();
        }
    }

    @Data
    static class RetryManage{
        private int nowRunTimes = 0;
        private int times;
        private long period;
        private RetryObj retryObj;
        private boolean finish = false;

        public RetryManage(int times, long period, RetryObj retryObj) {
            this.times = times;
            this.period = period;
            this.retryObj = retryObj;
        }

        public boolean run(){
            if (nowRunTimes >= times) {
                return true;
            }
            nowRunTimes++;
            return retryObj.run();
        }
    }

    abstract static class RetryObj{
        abstract boolean run();
    }


}
